#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
初始化数据库数据脚本
用于添加模拟的摄像头、告警和违规数据，确保前端页面能正常显示
"""

import os
import sys
import json
import uuid
import random
from datetime import datetime, timedelta
import logging

# 添加项目根目录到Python路径
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler("init_database.log"),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger("init_database")

# 导入数据库服务
from database import get_db_service
from sqlalchemy.exc import IntegrityError

# 确保上传目录存在
UPLOAD_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "uploads")
IMAGES_DIR = os.path.join(UPLOAD_DIR, "images")
os.makedirs(IMAGES_DIR, exist_ok=True)

class DatabaseInitializer:
    def __init__(self):
        self.db_service = get_db_service()
    
    def initialize_data(self):
        """初始化所有数据"""
        try:
            logger.info("开始初始化数据库数据...")
            
            # 初始化摄像头数据
            self._init_cameras()
            
            # 初始化违规记录和告警
            self._init_violations_and_alerts()
            
            # 初始化统计数据相关的配置
            self._init_configs()
            
            logger.info("数据库数据初始化完成！")
            
        except Exception as e:
            logger.error(f"数据库初始化失败: {str(e)}")
            raise
    
    def _init_cameras(self):
        """初始化摄像头数据"""
        logger.info("初始化摄像头数据...")
        
        def init_cameras_in_session(session):
            from database.models import Camera
            # 检查是否已有摄像头数据
            camera_count = session.query(Camera).count()
            if camera_count > 0:
                logger.info(f"已有{camera_count}个摄像头，跳过初始化")
                return
            
            # 创建模拟摄像头数据
            cameras_data = [
                {
                    "name": "摄像头1",
                    "description": "主路口摄像头",
                    "url": "rtsp://admin:password@192.168.1.101/stream1",
                    "camera_type": "rtsp",
                    "location": "东城区建国门大街",
                    "latitude": 39.9087,
                    "longitude": 116.4378,
                    "status": "active",
                    "is_enabled": True,
                    "fps": 25.0,
                    "resolution": "1920x1080"
                },
                {
                    "name": "摄像头2",
                    "description": "商业街监控",
                    "url": "rtsp://admin:password@192.168.1.102/stream1",
                    "camera_type": "rtsp",
                    "location": "西城区西单北大街",
                    "latitude": 39.9139,
                    "longitude": 116.3586,
                    "status": "active",
                    "is_enabled": True,
                    "fps": 25.0,
                    "resolution": "1920x1080"
                },
                {
                    "name": "摄像头3",
                    "description": "高速路监控",
                    "url": "rtsp://admin:password@192.168.1.103/stream1",
                    "camera_type": "rtsp",
                    "location": "朝阳区机场高速",
                    "latitude": 39.9428,
                    "longitude": 116.4809,
                    "status": "active",
                    "is_enabled": True,
                    "fps": 30.0,
                    "resolution": "2560x1440"
                },
                {
                    "name": "摄像头4",
                    "description": "住宅区入口",
                    "url": "rtsp://admin:password@192.168.1.104/stream1",
                    "camera_type": "rtsp",
                    "location": "海淀区中关村南大街",
                    "latitude": 39.9582,
                    "longitude": 116.3086,
                    "status": "inactive",
                    "is_enabled": False,
                    "fps": 20.0,
                    "resolution": "1280x720"
                },
                {
                    "name": "摄像头5",
                    "description": "停车场监控",
                    "url": "rtsp://admin:password@192.168.1.105/stream1",
                    "camera_type": "rtsp",
                    "location": "丰台区北京南站",
                    "latitude": 39.8652,
                    "longitude": 116.3785,
                    "status": "active",
                    "is_enabled": True,
                    "fps": 25.0,
                    "resolution": "1920x1080"
                },
                {
                    "name": "摄像头6",
                    "description": "学校门口",
                    "url": "rtsp://admin:password@192.168.1.106/stream1",
                    "camera_type": "rtsp",
                    "location": "东城区景山前街",
                    "latitude": 39.9163,
                    "longitude": 116.3977,
                    "status": "active",
                    "is_enabled": True,
                    "fps": 25.0,
                    "resolution": "1920x1080"
                },
                {
                    "name": "摄像头7",
                    "description": "医院入口",
                    "url": "rtsp://admin:password@192.168.1.107/stream1",
                    "camera_type": "rtsp",
                    "location": "西城区复兴门内大街",
                    "latitude": 39.9076,
                    "longitude": 116.3671,
                    "status": "disconnected",
                    "is_enabled": True,
                    "fps": 25.0,
                    "resolution": "1920x1080"
                },
                {
                    "name": "摄像头8",
                    "description": "公园入口",
                    "url": "rtsp://admin:password@192.168.1.108/stream1",
                    "camera_type": "rtsp",
                    "location": "海淀区颐和园路",
                    "latitude": 39.9992,
                    "longitude": 116.2751,
                    "status": "active",
                    "is_enabled": True,
                    "fps": 25.0,
                    "resolution": "1920x1080"
                }
            ]
            
            # 添加摄像头数据
            for camera_data in cameras_data:
                try:
                    camera = Camera(**camera_data)
                    session.add(camera)
                    session.flush()
                    logger.info(f"添加摄像头: {camera_data['name']}")
                except IntegrityError:
                    session.rollback()
                    logger.warning(f"摄像头已存在: {camera_data['name']}")
        
        # 使用db_service的执行查询方法
        self.db_service.execute_query(init_cameras_in_session)
    
    def _generate_alert_id(self):
        """生成告警ID"""
        return f"AL-{datetime.now().strftime('%Y%m%d')}-{uuid.uuid4().hex[:6].upper()}"
    
    def _create_alert_image(self, alert_id):
        """为告警创建图片路径（实际项目中应该有真实图片）"""
        # 这里只是创建一个虚拟的图片路径，实际项目中应该有真实图片
        image_filename = f"alert_{alert_id}.jpg"
        image_path = os.path.join(IMAGES_DIR, image_filename)
        
        # 创建一个空文件作为占位符
        with open(image_path, 'w') as f:
            f.write("This is a placeholder for alert image")
        
        return image_path
    
    def _init_violations_and_alerts(self):
        """初始化违规记录和告警"""
        logger.info("初始化违规记录和告警...")
        
        def init_violations_in_session(session):
            from database.models import Camera, Violation, Alert, Detection
            
            # 获取所有摄像头
            cameras = session.query(Camera).all()
            if not cameras:
                logger.error("没有摄像头数据，无法创建告警")
                return
            
            # 检查是否已有告警数据
            alert_count = session.query(Alert).count()
            if alert_count > 0:
                logger.info(f"已有{alert_count}个告警，跳过初始化")
                return
            
            # 违规类型列表
            violation_types = [
                "闯红灯", "超速", "违规停车", "逆行", "违规变道", 
                "压线行驶", "不礼让行人", "违法掉头", "占用应急车道"
            ]
            
            # 告警严重程度
            severity_levels = ["warning", "error", "critical"]
            
            # 创建50个模拟告警
            for i in range(50):
                try:
                    # 随机选择摄像头
                    camera = random.choice(cameras)
                    
                    # 随机生成时间戳（过去24小时内）
                    timestamp = datetime.now() - timedelta(hours=random.randint(0, 24), minutes=random.randint(0, 60))
                    
                    # 随机选择违规类型和严重程度
                    violation_type = random.choice(violation_types)
                    severity = random.choice(severity_levels)
                    
                    # 创建违规记录
                    violation = Violation(
                        camera_id=camera.id,
                        violation_type=violation_type,
                        severity=random.uniform(0.5, 1.0),
                        description=f"在{camera.location}检测到{violation_type}行为",
                        location=camera.location,
                        latitude=camera.latitude,
                        longitude=camera.longitude,
                        status=random.choice(['unhandled', 'processed', 'dismissed']),
                        details={
                            "vehicle_info": {
                                "plate_number": f"京A{random.randint(10000, 99999)}",
                                "vehicle_type": random.choice(["car", "truck", "bus", "motorcycle"]),
                                "color": random.choice(["red", "blue", "black", "white", "silver"])
                            },
                            "violation_details": {
                                "speed": random.randint(60, 120) if violation_type == "超速" else None,
                                "lane": random.randint(1, 4)
                            }
                        },
                        created_at=timestamp
                    )
                    session.add(violation)
                    session.flush()  # 获取violation.id
                    
                    # 创建告警记录
                    alert_id = self._generate_alert_id()
                    
                    # 为告警创建图片
                    image_path = self._create_alert_image(i + 1)
                    relative_image_path = os.path.relpath(image_path, os.path.dirname(os.path.abspath(__file__)))
                    
                    alert = Alert(
                        alert_id=alert_id,
                        alert_type=violation_type,
                        severity=severity,
                        source="camera",
                        message=f"摄像头{camera.name}检测到{violation_type}",
                        details={
                            "camera_info": {
                                "id": camera.id,
                                "name": camera.name,
                                "location": camera.location
                            },
                            "violation_info": {
                                "type": violation_type,
                                "severity": severity
                            }
                        },
                        snapshot_path=relative_image_path,
                        is_acknowledged=random.choice([True, False]),
                        acknowledged_by="system" if random.choice([True, False]) else None,
                        acknowledged_at=timestamp + timedelta(minutes=random.randint(5, 30)) if random.choice([True, False]) else None,
                        is_resolved=random.choice([True, False]),
                        resolved_at=timestamp + timedelta(minutes=random.randint(30, 120)) if random.choice([True, False]) else None,
                        violation_id=violation.id,
                        created_at=timestamp
                    )
                    session.add(alert)
                    
                    # 每10条打印一次信息
                    if (i + 1) % 10 == 0:
                        logger.info(f"已添加{i + 1}个告警")
                    
                except Exception as e:
                    logger.error(f"添加告警{i + 1}失败: {str(e)}")
                    session.rollback()
                    raise
            
            logger.info("告警数据初始化完成")
        
        # 使用db_service的执行查询方法
        self.db_service.execute_query(init_violations_in_session)
    
    def _init_configs(self):
        """初始化配置数据"""
        logger.info("初始化配置数据...")
        
        def init_configs_in_session(session):
            from database.models import Config
            
            # 检查是否已有配置数据
            config_count = session.query(Config).count()
            if config_count > 0:
                logger.info(f"已有{config_count}个配置，跳过初始化")
                return
            
            # 系统统计相关配置
            configs_data = [
                {
                    "key": "statistics.refresh_interval",
                    "value": 60,
                    "description": "统计数据刷新间隔（秒）",
                    "config_type": "general"
                },
                {
                    "key": "alerts.page_size",
                    "value": 20,
                    "description": "告警列表每页显示数量",
                    "config_type": "alert"
                },
                {
                    "key": "alerts.retention_days",
                    "value": 30,
                    "description": "告警数据保留天数",
                    "config_type": "alert"
                }
            ]
            
            # 添加配置数据
            for config_data in configs_data:
                try:
                    config = Config(**config_data)
                    session.add(config)
                    logger.info(f"添加配置: {config_data['key']}")
                except IntegrityError:
                    session.rollback()
                    logger.warning(f"配置已存在: {config_data['key']}")
        
        # 使用db_service的执行查询方法
        self.db_service.execute_query(init_configs_in_session)

if __name__ == "__main__":
    try:
        initializer = DatabaseInitializer()
        initializer.initialize_data()
        print("\n数据库初始化成功！")
    except Exception as e:
        print(f"\n数据库初始化失败: {str(e)}")
        sys.exit(1)